package design;

/**
 * 新一轮的「力扣杯」编程大赛即将启动，为了动态显示参赛者的得分数据，需要设计一个排行榜 Leaderboard。
 * <p>
 * 请你帮忙来设计这个 Leaderboard 类，使得它有如下 3 个函数：
 * <p>
 * addScore(playerId, score)：
 * 假如参赛者已经在排行榜上，就给他的当前得分增加 score 点分值并更新排行。
 * 假如该参赛者不在排行榜上，就把他添加到榜单上，并且将分数设置为 score。
 * top(K)：返回前 K 名参赛者的 得分总和。
 * reset(playerId)：将指定参赛者的成绩清零。题目保证在调用此函数前，该参赛者已有成绩，并且在榜单上。
 * 请注意，在初始状态下，排行榜是空的。
 * <p>
 * 来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/design-a-leaderboard
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */

import java.util.*;
import java.util.stream.Collectors;

/**
 * 解题思路：
 * 1、map 存储每个参赛选手的id 和得分
 * 2、优先队列 ProprietorQueue 利用 堆排序 返回前 k 个大小
 */
public class Leaderboard {

    private Map<Integer, Integer> map;

    public Leaderboard() {
        map = new HashMap<>();
    }

    public void addScore(int playerId, int score) {
        map.put(playerId, map.getOrDefault(playerId, 0) + score);
    }

    /**
     * 排序 ，取前 k 个值相加
     * @param K
     * @return
     */
    public int top(int K) {
        int sum = 0;
        List<Integer> values = map.values().stream().sorted(Comparator.reverseOrder()).collect(Collectors.toList());
        for (int i = 0; i < K; i++) {
            sum += values.get(i);
        }
        return sum;

    }

    public void reset(int playerId) {
        map.remove(playerId);
    }
}
